#include<cstdio>
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<unistd.h>
#include<errno.h>
#include<sys/epoll.h>
#include<fstream>
#include <sys/stat.h>
#include <fcntl.h>
#include<sys/stat.h>
#include<time.h>

#include"Fsm.h"
#include"../tool/Logger.h"
#include"Httpparse.h"


char Fsm::pwd_path[256] = "";
Fsm* Fsm::fsm = new Fsm;



char *get_mime(char* name){
    char* dot;
    dot = strrchr(name, '.');
    if (dot == (char*)0)
        return "text/plain; charset=utf-8";
    if (strcmp(dot, ".html") == 0 || strcmp(dot, ".htm") == 0)
        return "text/html; charset=utf-8";
    if (strcmp(dot, ".jpg") == 0 || strcmp(dot, ".jpeg") == 0)
        return "image/jpeg";
    if (strcmp(dot, ".gif") == 0)
        return "image/gif";    
    if (strcmp(dot, ".png") == 0)
        return "image/png";
    if (strcmp(dot, ".css") == 0)
        return "text/css";
    if (strcmp(dot, ".au") == 0)
        return "audio/basic";
    if (strcmp( dot, ".wav") == 0)
        return "audio/wav";
    if (strcmp(dot, ".avi") == 0)
        return "video/x-msvideo";
    if (strcmp(dot, ".mov") == 0 || strcmp(dot, ".qt") == 0)
        return "video/quicktime";
    if (strcmp(dot, ".mpeg") == 0 || strcmp(dot, ".mpe") == 0)
        return "video/mpeg";
    if (strcmp(dot, ".vrml") == 0 || strcmp(dot, ".wrl") == 0)
        return "model/vrml";
    if (strcmp(dot, ".midi") == 0 || strcmp(dot, ".mid") == 0)
        return "audio/midi";
    if (strcmp(dot, ".mp3") == 0)
        return "audio/mpeg";
    if (strcmp(dot, ".ogg") == 0)
        return "application/ogg";
    if (strcmp(dot, ".pac") == 0)
        return "application/x-ns-proxy-autoconfig";


    if (strcmp(dot, ".svg") == 0)
        return "image/svg+xml";


    return "text/plain; charset=utf-8";
}


int send_file(int fd ,char *pwd){
    char *type_file = get_mime(pwd);

    struct stat buf_stat;
    int ret = stat(pwd,&buf_stat);
    if(ret != 0)return -1;

    // debug("file pwd = %s",pwd);
    // debug("size of file = %d",buf_stat.st_size);

    int fd_file = open(pwd,O_RDONLY);
    if(fd_file == -1)return -1;

    char txt[buf_stat.st_size]="";
    
    int len = read(fd_file,txt,sizeof(txt));
    write(fd,txt,sizeof(txt));
    
    close(fd_file);
    debug("send_file");
    return 0;
}

int send_response_head(int fd,int ver,int res){
    char txt[64]="";

    if(ver == HTTP1_0) strcat(txt,"HTTP/1.0");
    else if(ver == HTTP1_1) strcat(txt,"HTTP/1.1");
    else return -1;

    if(res == Res_OK) strcat(txt," 200 OK\r\n");
    else if(res == Res_NOT_FOUND) strcat(txt," 404 	Not Found\r\n");
    else return -1;

    write(fd,txt,strlen(txt));
    debug("send_response_head");
    return 0;
}

int send_headers(int fd,char *pwd){
    
    char buf[64] = "";

    char *type_file = get_mime(pwd);
    
    strcat(buf,"Content-Type:");
    strcat(buf,type_file);
    strcat(buf,"\r\n");

    strcat(buf,"\r\n");


    debug("send_headers %d",fd);
    try
    {
        write(fd,buf,strlen(buf));
    }
    catch(...)
    {
        
    }
    
    debug("send_headers");
    return 0;
}

int Fsm::method_get(const int &epfd,const struct epoll_event &ev,const Httpparse &hp){
    debug("method_get start");
    int fd = ev.data.fd;

    char pwd[256]="";
	strcat(pwd,pwd_path);

    if(strcmp(hp.url,"/")==0){
        strcat(pwd,"/Main.html");
    }else{
        strcat(pwd,hp.url);
    }

    int ret;
    // debug("%s",pwd);

    ret = access(pwd,F_OK);
    
    if(ret == -1){
        strcat(pwd,pwd_path);
        strcat(pwd,"/404.html");
        
        int w1 = send_response_head(fd,hp.version,Res_NOT_FOUND);
        int w2 = send_headers(fd,pwd);
        int w3 = send_file(fd,pwd);
        if(w1==-1 || w2 == -1 || w3 == -1){
            return -1;
        }
    }else{
        int w1 = send_response_head(fd,hp.version,Res_OK);
        int w2 = send_headers(fd,pwd);
        int w3 = send_file(fd,pwd);
        if(w1==-1 || w2 == -1 || w3 == -1){
            return -1;
        }
    }
    
    return 0;
}

void Fsm::response(int epfd,struct epoll_event ev){
    
    int fd = ev.data.fd;

    // epoll_ctl(epfd,EPOLL_CTL_DEL,fd,&ev);


    //解析请求头
    Httpparse hp(epfd,ev);
    if(hp.status == -1){
        // epoll_ctl(epfd,EPOLL_CTL_DEL,fd,&ev);
        close(fd);
        return;
    }

    debug("%d %d %s",hp.version,hp.method,hp.url);

    if(hp.method == M_GET){
        int w = method_get(epfd,ev,hp);
    }else if(hp.version == M_POST){
        int w = method_get(epfd,ev,hp);
    }else{

    }

    // epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);
    // epoll_ctl(epfd,EPOLL_CTL_DEL,fd,&ev);
    close(fd);
}